package org.dashboard.controller;


import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.dashboard.bean.AdDataset;
import org.dashboard.bean.JsonResponse;
import org.dashboard.service.AdDatasetService;
import org.dashboard.service.AdExcelService;
import org.dashboard.service.ExcelUtilService;
import org.dashboard.utils.NameCastTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.jar.JarEntry;

@RestController
@RequestMapping("/common/excel")
public class AdExcelController extends BaseController {

    private static final Logger logger = LoggerFactory.getLogger(AdDatasourceController.class);

    private static final String EXCEL_FOLDER = "excel";

    @Value("${web.upload.base.path}")
    private String uploadBasePath;

    @Autowired
    private ExcelUtilService excelUtilService;

    @Reference
    private AdExcelService adExcelService;

    @Reference
    private AdDatasetService adDatasetService;


    @RequestMapping(value = "/upload", method = RequestMethod.POST, produces = MediaType.MULTIPART_FORM_DATA_VALUE)
    @ResponseBody
    public JsonResponse handleExcelUpload(@RequestParam("file") MultipartFile file) {

        try {

            if (file.isEmpty()) {
                return JsonResponse.failed();
            }

            String fullPath = uploadBasePath + File.separator + EXCEL_FOLDER;
            File uploadFilePath = new File(fullPath);

            if (!uploadFilePath.exists()) {
                if (!uploadFilePath.mkdir()) {
                    return JsonResponse.failed();
                }
            }

            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");

            String fileOriginalName = file.getOriginalFilename();
            String fileExtend = fileOriginalName.substring(fileOriginalName.lastIndexOf(".") + 1);
            String fileJustName = fileOriginalName.substring(0, fileOriginalName.lastIndexOf("."));

            String diskFileName = fileJustName + "_" + dateFormat.format(new Date()) + "." + fileExtend;
            String fileFullPath = fullPath + File.separator + diskFileName;

            byte[] bytes = file.getBytes();

            FileOutputStream fileOutputStream = new FileOutputStream(new File(fileFullPath));
            BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
            bufferedOutputStream.write(bytes);
            bufferedOutputStream.close();

            Map<String, Object> allData = excelUtilService.parseExcelData(fileFullPath, fileJustName, diskFileName);

            JsonResponse jsonResponse = new JsonResponse();
            jsonResponse.setData(allData);

            jsonResponse.setCode(1);
            jsonResponse.setResult("success");
            return jsonResponse;

        } catch (IOException e) {
            logger.error("handleExcelUpload", e);
        }

        return JsonResponse.success();
    }


    @RequestMapping(value = "/load", method = RequestMethod.POST, produces = MediaType.MULTIPART_FORM_DATA_VALUE)
    @ResponseBody
    public JsonResponse handleExcelLoad(HttpServletRequest request) {

        String datasetCode = request.getParameter("datasetCode");

        AdDataset adDataset = adDatasetService.selectAdDatasetByCode(datasetCode);
        if (adDataset == null) {
            return JsonResponse.failed();
        }

        JSONObject datasetObj = (JSONObject) JSON.parse(adDataset.getDatasetData());
        if (datasetObj == null) {
            return JsonResponse.failed();
        }
        String fullPath = uploadBasePath + File.separator + EXCEL_FOLDER;
        String excelFileName = datasetObj.getJSONObject("DataServiceMeta").getString("ExcelFileName");
        String excelFullPath = fullPath + File.separator + excelFileName;

        List<Object[]> excelData = excelUtilService.loadExcelData(excelFullPath);

        JsonResponse jsonResponse = new JsonResponse();
        jsonResponse.setData(excelData);

        jsonResponse.setCode(1);
        jsonResponse.setResult("success");
        return jsonResponse;
    }


    @RequestMapping(value = "/update", method = RequestMethod.POST, produces = MediaType.MULTIPART_FORM_DATA_VALUE)
    @ResponseBody
    public JsonResponse handleExcelUpdate(HttpServletRequest request) {

        String datasetCode = request.getParameter("datasetCode");
        String datasetGrid = request.getParameter("datasetGrid");

        AdDataset adDataset = adDatasetService.selectAdDatasetByCode(datasetCode);
        if (adDataset == null) {
            return JsonResponse.failed();
        }

        JSONObject datasetObj = (JSONObject) JSON.parse(adDataset.getDatasetData());
        if (datasetObj == null) {
            return JsonResponse.failed();
        }

        JSONArray datasetArray = (JSONArray) JSON.parse(datasetGrid);
        if (datasetArray == null) {
            return JsonResponse.failed();
        }

        List<Object[]> excelData = new ArrayList<>();
        for (Object o : datasetArray) {
            if (o instanceof JSONArray) {
                excelData.add(((JSONArray) o).toArray());
            }
        }

        String fullPath = uploadBasePath + File.separator + EXCEL_FOLDER;
        String excelOldFileName = datasetObj.getJSONObject("DataServiceMeta").getString("ExcelFileName");
        String excelOldFullPath = fullPath + File.separator + excelOldFileName;

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        String excelNewFileExtend = excelOldFileName.substring(excelOldFileName.lastIndexOf(".") + 1);
        String excelNewFileName = adDataset.getDatasetName() + "_" + dateFormat.format(new Date()) + "." + excelNewFileExtend;
        String excelNewFullPath = fullPath + File.separator + excelNewFileName;

        excelUtilService.updateExcelData(excelOldFullPath, excelNewFullPath, excelData);

        ((JSONObject) datasetObj.get("DataServiceMeta")).put("ExcelFileName", excelNewFileName);
        adDataset.setDatasetData(JSON.toJSONString(datasetObj));

        adDatasetService.updateByPrimaryKeyWithBLOBs(adDataset);

        return JsonResponse.success();
    }

}
